package com.tongtong.stsuserapi.service.base.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tongtong.stscommon.enumration.*;
import com.tongtong.stscommon.exception.STSResourcesOperationException;
import com.tongtong.stscommon.exception.STSOrderOperationException;
import com.tongtong.stscommon.message.STSMessage;
import com.tongtong.stscommon.message.STSSuccessMessage;
import com.tongtong.stscommon.utils.checker.ObjectChecker;
import com.tongtong.stsuserapi.dao.ItemDao;
import com.tongtong.stsuserapi.dao.OrderDao;
import com.tongtong.stsuserapi.dao.UserDao;
import com.tongtong.stsuserapi.pojo.Item;
import com.tongtong.stsuserapi.pojo.Order;
import com.tongtong.stsuserapi.pojo.User;
import com.tongtong.stsuserapi.pojo.search.ItemSearch;
import com.tongtong.stsuserapi.service.base.ItemService;
import com.tongtong.stsuserapi.service.qiniu.QiniuService;
import io.netty.util.internal.StringUtil;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ItemServiceImpl implements ItemService {

	@Autowired
	ItemDao itemDao;

	@Autowired
	QiniuService qiniuService;

	@Autowired
	OrderDao orderDao;

	@Autowired
	UserDao userDao;

	@Override
	public STSMessage postItem(Long ownerId, Item item) {

		ObjectChecker.ObjectsFromHTTPNullCheck(item);

		User owner = userDao.selectById(ownerId);
		ObjectChecker.ObjectsFromDBNullCheck(owner);

		item.setOwnerId(ownerId);
		item.setReleaseTime(new Timestamp(System.currentTimeMillis()));
		item.setUpdateTime(item.getReleaseTime());
		item.setAddress(owner.getAddress());

		// TODO 可能需要限制物品信息不为null
		try {
			itemDao.insert(item);
		} catch (Exception e) {
			throw new STSResourcesOperationException(Status.AddResourcesError, e.getMessage());
		}

		Map<String,String> map = new HashMap<>();
		map.put("itemId",item.getId().toString());

		return STSSuccessMessage.from(map);
	}

	@Override
	public STSMessage getItemInfoById(Long itemId) {

		Item item = itemDao.selectById(itemId);
		ObjectChecker.ObjectsFromDBNullCheck(item);

		User user = userDao.selectById(item.getOwnerId());
		ObjectChecker.ObjectsFromDBNullCheck(user);

		HashMap<String,Object> map = new HashMap<>();
		map.put("item",item);

		HashMap<String,String> sellerInfo = new HashMap<>();
		sellerInfo.put("phone", user.getPhone());
		sellerInfo.put("qq",user.getQq());
		sellerInfo.put("wechat",user.getWechat());

		map.put("sellerInfo",sellerInfo);

		return STSSuccessMessage.from(map);
	}

	@Override
	public STSMessage updateItemById(Item item) {

		// 传入对象为空
		ObjectChecker.ObjectsFromHTTPNullCheck(item);

		item.setUpdateTime(new Timestamp(System.currentTimeMillis())); // 更新时间
		int affectRows;
		try {
			affectRows = itemDao.updateById(item);
		} catch (Exception e) {
			throw new STSResourcesOperationException(Status.DeleteResourcesError,e.getMessage());
		}
		if(affectRows<1)
			throw new STSResourcesOperationException(Status.DeleteResourcesError,Message.ObjectCanNotFound);

		return STSSuccessMessage.from(Status.OK, Message.OK);
	}

	public STSMessage uploadIMGById(Long itemId, MultipartFile file) throws Exception {

		// 获取指定物品
		Item item = itemDao.selectById(itemId);
		ObjectChecker.ObjectsFromDBNullCheck(item);

		// 删除原图片
		String pre_url = item.getImageUrl();
		if(!StringUtil.isNullOrEmpty(pre_url)) {
			qiniuService.Delete(pre_url);
		}

		// 更新图片
		String url = qiniuService.Upload(file, FileType.ItemIMG).get("url").toString();
		item.setImageUrl(url);
		item.setUpdateTime(new Timestamp(System.currentTimeMillis())); // 更新时间

		try {
			itemDao.updateById(item);
		} catch (Exception e) {
			throw new STSResourcesOperationException(Status.UpdateResourcesError,e.getMessage());
		}

		Map<String,String> map = new HashMap<>();
		map.put("url",url);

		return STSSuccessMessage.from(map);
	}

	@Override
	public STSMessage deleteItemById(Long id) {

		int affectRows;
		try {
			affectRows = itemDao.deleteById(id);
		} catch (Exception e) {
			throw new STSResourcesOperationException(Status.DeleteResourcesError,e.getMessage());
		}
		if(affectRows<1)
			throw new STSResourcesOperationException(Status.DeleteResourcesError,Message.ObjectCanNotFound);

		return STSSuccessMessage.from(Status.OK,Message.OK);
	}

	@Override
	public STSMessage searchItemByPage(ItemSearch itemSearch, int page, int pageSize) {

		ObjectChecker.ObjectsFromHTTPNullCheck(itemSearch);

		HashMap<String,Object> map = new HashMap<>();

		List<Item> list = itemDao.dynamicSelect(itemSearch, page, pageSize);
		Long len = itemDao.dynamicSelectCount(itemSearch);

		map.put("list",list);
		map.put("len",len);

		return STSSuccessMessage.from(map);
	}

	@Override
	public STSMessage getPublishedItems(Long userid) {

		LambdaQueryWrapper<Item> lqw = new LambdaQueryWrapper<>();
		lqw.eq(Item::getOwnerId,userid);
		List<Item> items = itemDao.selectList(lqw);

		HashMap<String,Object> map = new HashMap<>();
		map.put("len",items.size());
		map.put("list",items);

		return STSSuccessMessage.from(map);
	}

	@Override
	public STSMessage getBookedOrSoldItems(Long userid, Integer orderState) {

		LambdaQueryWrapper<Order> lqw = new LambdaQueryWrapper<>();
		lqw.eq(Order::getSellerId,userid);
		lqw.eq(Order::getOrderState,orderState);
		List<Order> orders = orderDao.selectList(lqw);

		List<HashMap<String,Object>> list = new ArrayList<>();

		for (Order order:orders)
		{
			// 查询买家信息
			User user = userDao.selectById(order.getUserId());
			ObjectChecker.ObjectsFromDBNullCheck(user);
			// 封装买家信息
			HashMap<String,Object> buyer = new HashMap<>();
			buyer.put("phone",user.getPhone());
			buyer.put("address",user.getAddress());
			buyer.put("qq",user.getQq());
			buyer.put("wechat",user.getWechat());
			// 封装买家信息和订单信息
			HashMap<String,Object> temp = new HashMap<>();
			temp.put("orderInfo",order);
			temp.put("buyerInfo",buyer);
			// 添加到列表中
			list.add(temp);
		}

		HashMap<String,Object> map = new HashMap<>();
		map.put("len",list.size());
		map.put("list",list);

		return STSSuccessMessage.from(map);
	}

	@Override
	public void orderItem(Long itemId, Integer quantity) {

		Item item = itemDao.selectById(itemId);
		ObjectChecker.ObjectsFromDBNullCheck(item);

		if(item.getItemState() != ItemState.PUBLISHED) {
			throw new STSOrderOperationException(Status.ItemOrderedOrSoldOut,Message.ItemOrderedOrSoldOut);
		}

		Integer currentQuantity = item.getQuantity(); // 获取当前库存数量
		Integer currentOrderQuantity = item.getOrderedQuantity(); //获取当前预定数量

		// 库存不足
		if(currentOrderQuantity+quantity > currentQuantity) {
			throw new STSOrderOperationException(Status.QuantityExceeded, Message.QuantityExceeded);
		}

		item.setOrderedQuantity(currentOrderQuantity+quantity);
		if(currentOrderQuantity+quantity == currentQuantity) {
			item.setItemState(ItemState.ORDERED);
		}

		try	{
			itemDao.updateById(item);
		} catch (Exception e) {
			throw new STSResourcesOperationException(Status.UpdateResourcesError,e.getMessage());
		}

	}

	@Override
	public void cancelOrder(Long orderId) {

		Order order = orderDao.selectById(orderId);
		ObjectChecker.ObjectsFromDBNullCheck(order);

		Integer quantity = order.getItemCount();

		Item item = itemDao.selectById(order.getItemId());
		ObjectChecker.ObjectsFromDBNullCheck(item);
		Integer currentOrderQuantity = item.getOrderedQuantity(); //获取当前预定数量

		// 判断库存数量是否正常
		if(currentOrderQuantity - quantity < 0) {
			throw new STSOrderOperationException(Status.ItemOrderedOrSoldOut,Message.OrderStateError);
		}

		item.setOrderedQuantity(currentOrderQuantity-quantity);
		if(item.getItemState()==ItemState.ORDERED) {
			item.setItemState(ItemState.PUBLISHED);
		}

		try	{
			itemDao.updateById(item);
		} catch (Exception e) {
			throw new STSResourcesOperationException(Status.UpdateResourcesError,e.getMessage());
		}
	}

	@Override
	public void soldItem(Long orderId) {

		Order order = orderDao.selectById(orderId);
		ObjectChecker.ObjectsFromDBNullCheck(order);
		Integer quantity = order.getItemCount();

		Item item = itemDao.selectById(order.getItemId());
		ObjectChecker.ObjectsFromDBNullCheck(item);
		Integer currentQuantity = item.getQuantity(); // 获取当前库存数量
		Integer currentOrderQuantity = item.getOrderedQuantity(); //获取当前预定数量

		// 判断库存数量是否正常
		if(currentOrderQuantity - quantity < 0 || currentOrderQuantity > currentQuantity) {
			throw new STSOrderOperationException(Status.ItemOrderedOrSoldOut,Message.OrderStateError);
		}

		item.setQuantity(currentQuantity - quantity);
		item.setOrderedQuantity(currentOrderQuantity-quantity);
		if(currentQuantity - quantity == 0) {
			item.setItemState(ItemState.SOLDOUT);
		}

		try	{
			itemDao.updateById(item);
		} catch (Exception e) {
			throw new STSResourcesOperationException(Status.UpdateResourcesError,e.getMessage());
		}
	}
}
